﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Text;

namespace Tanmia.Basis
{
    public class ObjectValidator
    {
        private readonly object instance;

        public ICollection<ValidationResult> ValidationResults { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="DataErrorInfoSupport"/> class.
        /// </summary>
        /// <param name="instance">The instance.</param>
        /// <exception cref="ArgumentNullException">instance must not be <c>null</c>.</exception>
        public ObjectValidator(object instance)
        {
            if (instance == null)
                throw new ArgumentNullException("instance");

            this.instance = instance;
        }


        /// <summary>
        /// Gets an error message indicating what is wrong with this object.
        /// </summary>
        /// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns>
        public string Error
        {
            get
            {
                ValidationResults = new List<ValidationResult>();
                ValidationContext ami = new ValidationContext(instance, null, null);
                Validator.TryValidateObject(instance, new ValidationContext(instance, null, null), ValidationResults, true);

                StringBuilder errorBuilder = new StringBuilder();
                foreach (ValidationResult validationResult in ValidationResults)
                    errorBuilder.AppendInNewLine(validationResult.ErrorMessage);

                return errorBuilder.ToString();
            }
        }

        /// <summary>
        /// Gets the error message for the property with the given name.
        /// </summary>
        /// <param name="memberName">The name of the property whose error message to get.</param>
        /// <returns>The error message for the property. The default is an empty string ("").</returns>
        public string this[string columnName]
        {
            get
            {
                ValidationResults = new List<ValidationResult>();

                PropertyDescriptor property = TypeDescriptor.GetProperties(instance)[columnName];

                if (property == null)
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                        "The specified member {0} was not found on the instance {1}", columnName, GetType()));

                Validator.TryValidateProperty(property.GetValue(instance), new ValidationContext(instance, null, null) { MemberName = columnName }, ValidationResults);

                StringBuilder errorBuilder = new StringBuilder();
                foreach (ValidationResult validationResult in ValidationResults)
                    errorBuilder.AppendInNewLine(validationResult.ErrorMessage);

                return errorBuilder.ToString();
            }
        }
    }
}
